home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / EXTERN / EASYGRAP.I < prev    next >
Encoding:
Modula Implementation  |  1989-08-22  |  15.8 KB  |  553 lines

  1. IMPLEMENTATION MODULE EasyGraphics;
  2.  
  3. IMPORT InOut;
  4.  
  5.  
  6. (*  --------------------------------------------------------------------------
  7.  *  System-Version: MOS 1.1
  8.  *  --------------------------------------------------------------------------
  9.  *  Version       : 0.01
  10.  *  --------------------------------------------------------------------------
  11.  *  Text-Version  : V#0015
  12.  *  --------------------------------------------------------------------------
  13.  *  Modul-Holder  : Manuel Chakravarty
  14.  *  --------------------------------------------------------------------------
  15.  *  Copyright February 89 by Manuel Chakravarty
  16.  *  Vertriebsrechte für ATARI ST unter MEGAMAX Modula-2
  17.  *                  liegen bei Application Systems Heidelberg
  18.  *  --------------------------------------------------------------------------
  19.  *  MCH : Manuel Chakravarty
  20.  *  --------------------------------------------------------------------------
  21.  *  Datum    Autor  Version  Bemerkung (Arbeitsbericht)
  22.  *
  23.  *  01.02.89 MCH    0.01     Erste Definition nach 'EasyGraph' von MAC II
  24.  *  --------------------------------------------------------------------------
  25.  *  Modul-Beschreibung:
  26.  *
  27.  *  Grundlegende Grafikroutinen in einem Fenster.
  28.  *  --------------------------------------------------------------------------
  29.  *)
  30.  
  31. (*  =========== ZU TUN: ==============
  32.  *
  33.  *  -- 'Point' benutzen in Def.-Modul
  34.  *
  35.  *  -- 'baseLine' nicht konst. def., sondern erfragen
  36.  *
  37.  *  -- Turtle sollte ihre Position genauer speichern, um Rundungsfehler
  38.  *     bei 'Move' zu vermeiden.
  39.  *
  40.  *  -- 'MathLib0' wegrationalisieren
  41.  *
  42.  *  =========== DOCU: ================
  43.  *
  44.  *)
  45.  
  46.  
  47. FROM SYSTEM IMPORT ADDRESS,
  48.                    ADR;
  49.  
  50. FROM Storage IMPORT ALLOCATE, DEALLOCATE;
  51.  
  52. FROM MOSGlobals IMPORT MemArea, GeneralErr, OutOfMemory;
  53.  
  54. FROM MOSCtrl IMPORT Stack;
  55.  
  56. FROM PrgCtrl IMPORT TermCarrier,
  57.                     CatchProcessTerm;
  58.  
  59. FROM MathLib0 IMPORT pi,
  60.                      sin, cos, entier;
  61.  
  62. FROM GrafBase IMPORT BitOperation, Point, PtrMemFormDef, MemFormDef,
  63.                      Rectangle, white, black,
  64.                      Pnt, TransRect, MinPoint, Rect, GetScreen, SetScreen;
  65.  
  66. FROM GEMGlobals IMPORT FillType, MarkerType, LineType, TEffectSet;
  67.  
  68. FROM GEMEnv IMPORT RC, DeviceHandle, GemHandle, PtrDevParm, DevParm,
  69.                    InitGem, ExitGem, CurrGemHandle, SetCurrGemHandle,
  70.                    DeviceParameter;
  71.  
  72. FROM VDIControls IMPORT SetClipping, DisableClipping;
  73.  
  74. FROM VDIAttributes IMPORT SetFillColor, SetFillType, SetMarkerColor,
  75.                           SetMarkerType, SetLineColor, SetLineType,
  76.                           SetTextColor, SetTextEffects;
  77.  
  78. FROM VDIOutputs IMPORT FillRectangle, Mark, Line, GrafText;
  79. IMPORT VDIOutputs;
  80.  
  81. FROM VDIRasters IMPORT CopyOpaque;
  82.  
  83. FROM VDIInquires IMPORT TextExtent;
  84.  
  85. FROM EventHandler IMPORT ShareTime;
  86.  
  87. FROM WindowBase IMPORT Window, WdwElement, WdwElemSet, ScrollCopyAlways,
  88.                        SetWdwStrMode, ScrollMode, SliderState, NoWindow,
  89.                        CreateWindow, DeleteWindow, OpenWindow, CloseWindow,
  90.                        SetWindowString, CalculateSliders, WindowCoordinates,
  91.                        RedrawWindow, UpdateWindow;
  92.  
  93.  
  94. CONST   noErrorTrap     = 6;
  95.  
  96.         mainWdwName     = ' Std - Graphics ';
  97.         
  98.         baseLine        = 4;
  99.  
  100. TYPE    turtleDesc      = RECORD
  101.                             pos  : Point;
  102.                             angle: INTEGER;
  103.                           END;
  104.         
  105.         graphWdw        = RECORD
  106.                             turtle: turtleDesc;
  107.                             wdw   : Window;
  108.                             screen: MemFormDef;
  109.                           END;
  110.         ptrGraphWdw     = POINTER TO graphWdw;
  111.  
  112.  
  113. VAR     mainGraphWdw    : graphWdw;
  114.  
  115.         dev             : DeviceHandle;
  116.         gemHdl          : GemHandle;
  117.         
  118.         VoidADR         : ADDRESS;
  119.         VoidI           : INTEGER;
  120.  
  121.  
  122.                         (*  misc. proc.s  *)
  123.                         (*  ============  *)
  124.                         
  125. (*  saveCurrHdl -- Rettet das aktuelle GEM-Hdl. in 'saveArea' und setzt
  126.  *                 stattdessen das handle von 'EasyGraphics' ein. Tritt
  127.  *                 beim Setzen ein Fehler auf, so wird ein Laufzeitfehler
  128.  *                 ausgelößt.
  129.  *)
  130.  
  131. PROCEDURE saveCurrHdl (VAR saveArea : GemHandle);
  132.  
  133.   (*$L-*)
  134.   BEGIN
  135.     ASSEMBLER
  136.         JSR     CurrGemHandle
  137.         MOVE.L  -(A3),D0
  138.         MOVE.L  -(A3),A0
  139.         MOVE.L  D0,(A0)
  140.         
  141.         MOVE.L  gemHdl,(A3)+
  142.         SUBQ.L  #2,A7
  143.         MOVE.L  A7,(A3)+
  144.         JSR     SetCurrGemHandle
  145.         TST.W   (A7)+
  146.         BNE     ende
  147.         
  148.         TRAP    #noErrorTrap
  149.         DC.W    GeneralErr - $E000
  150.         ACZ     "EasyGraph.:Can't set own GEMHdl"
  151.         SYNC
  152.         
  153. ende
  154.     END;
  155.   END saveCurrHdl;
  156.   (*$L=*)
  157.  
  158. (*  restoreCurrHdl -- Setzt 'saveArea' als GEM-Hdl. ein. Falls dabei ein
  159.  *                    Fehlere auftritt, wird ein Laufzeitfehler ausgelößt.
  160.  *)
  161.         
  162. PROCEDURE restoreCurrHdl (saveArea : GemHandle);
  163.  
  164.   (*$L-*)
  165.   BEGIN
  166.     ASSEMBLER
  167.         TST.L   -4(A3)
  168.         BEQ     ende            ; jump, if 'saveArea = noGem'
  169.         
  170.         SUBQ.L  #2,A7
  171.         MOVE.L  A7,(A3)+
  172.         JSR     SetCurrGemHandle
  173.         TST.W   (A7)+
  174.         BNE     ende
  175.         
  176.         TRAP    #noErrorTrap
  177.         DC.W    GeneralErr - $E000
  178.         ACZ     "EasyGraph.:Can't set old GEMHdl"
  179.         SYNC
  180.         
  181. ende
  182.     END;
  183.   END restoreCurrHdl;
  184.   (*$L=*)
  185.   
  186. (*  reportOutOfMem -- Raises a 'Out of memory' runtime error.
  187.  *                    It is possible to continue from the error.
  188.  *)
  189.  
  190. PROCEDURE reportOutOfMem;
  191.  
  192.   BEGIN
  193.     ASSEMBLER
  194.         TRAP    #noErrorTrap
  195.         DC.W    OutOfMemory - $6000
  196.     END;
  197.   END reportOutOfMem;
  198.  
  199. PROCEDURE cantInitGem;
  200.  
  201.   BEGIN
  202.     ASSEMBLER
  203.         TRAP    #noErrorTrap
  204.         DC.W    GeneralErr - $E000
  205.         ACZ     "EasyGraph.:Can't init. GEM"
  206.         SYNC
  207.     END;
  208.   END cantInitGem;
  209.  
  210.  
  211.                         (*  misc. proc.s  *)
  212.                         (*  ============  *)
  213.  
  214. PROCEDURE newScreen (new: ADDRESS; VAR old: ADDRESS);
  215.  
  216.   BEGIN
  217.     GetScreen (old, VoidADR, VoidI);
  218.     SetScreen (new, ADDRESS (-1L), -1);
  219.   END newScreen;
  220.  
  221. PROCEDURE restoreScreen (old: ADDRESS);
  222.  
  223.   BEGIN
  224.     SetScreen (old, ADDRESS (-1L), -1);
  225.   END restoreScreen;
  226.  
  227. PROCEDURE setClipping (screen: MemFormDef);
  228.  
  229.   BEGIN
  230.     SetClipping (dev, Rect (0, 0, screen.w, screen.h));
  231.   END setClipping;
  232.  
  233. PROCEDURE disableClipping;
  234.  
  235.   BEGIN
  236.     DisableClipping (dev);
  237.   END disableClipping;
  238.   
  239.   
  240.                         (*  wdw. server  *)
  241.                         (*  ===========  *)
  242.                         
  243. PROCEDURE redrawServer (wdw  : Window;
  244.                         env  : ADDRESS;
  245.                         frame: Rectangle);
  246.  
  247.   VAR   graphWdwPtr: ptrGraphWdw;
  248.         physScreen : MemFormDef;
  249.         sourceFrame: Rectangle;
  250.  
  251.   BEGIN
  252.     graphWdwPtr := ptrGraphWdw (env);
  253.     
  254.     physScreen.start := NIL;
  255.     
  256.     IF (frame.w # 0) AND (frame.h # 0) THEN
  257.     
  258.       sourceFrame := TransRect (frame, WindowCoordinates (graphWdwPtr^.wdw,
  259.                                                           MinPoint (frame)));
  260.       CopyOpaque (dev, ADR (graphWdwPtr^.screen), ADR (physScreen),
  261.                   sourceFrame, frame, onlyS);
  262.                   
  263.     END;
  264.   END redrawServer;
  265.   
  266. PROCEDURE activeServer (wdw: Window;
  267.                         env: ADDRESS);
  268.  
  269.   END activeServer;
  270.   
  271. PROCEDURE closeServer (wdw: Window;
  272.                        env: ADDRESS);
  273.  
  274.   END closeServer;
  275.   
  276. PROCEDURE moveSizeServer (wdw    : Window;
  277.                           env    : ADDRESS;
  278.                           frame  : Rectangle;
  279.                           maxWork: Rectangle): Rectangle;
  280.  
  281.   BEGIN
  282.     RETURN frame
  283.   END moveSizeServer;
  284.   
  285. PROCEDURE scrollServer (wdw    : Window;
  286.                         env    : ADDRESS;
  287.                         toDo   : ScrollMode;
  288.                         sliders: SliderState): SliderState;
  289.  
  290.   VAR   graphWdwPtr: ptrGraphWdw;
  291.  
  292.   BEGIN
  293.     graphWdwPtr := ptrGraphWdw (env);
  294.     
  295.     WITH sliders DO
  296.       CASE toDo OF
  297.         pageUp     : IF vertPos > vertSize THEN vertPos := vertPos - vertSize
  298.                      ELSE vertPos := 0 END|
  299.         pageDown   : vertPos := vertPos + vertSize|
  300.         pageLeft   : IF horPos > horSize THEN horPos := horPos - horSize
  301.                      ELSE horPos := 0 END|
  302.         pageRight  : horPos := horPos + horSize|
  303.         rowUp      : IF vertPos > 800 THEN vertPos := vertPos - 800
  304.                      ELSE vertPos := 0 END|
  305.         columnLeft : IF horPos > 800 THEN horPos := horPos - 800
  306.                      ELSE horPos := 0 END|
  307.         rowDown    : vertPos := vertPos + 800|
  308.         columnRight: horPos := horPos + 800|
  309.       END;
  310.       
  311.       sliders := CalculateSliders (wdw, horPos, vertPos, graphWdwPtr^.screen.w,
  312.                                    graphWdwPtr^.screen.h);
  313.     
  314.     END;
  315.     
  316.     RETURN sliders
  317.     
  318.   END scrollServer;
  319.   
  320.  
  321.                         (*  exported proc.s  *)
  322.                         (*  ===============  *)
  323.  
  324. PROCEDURE Clear ();
  325.  
  326.   VAR   oldScreen: ADDRESS;
  327.  
  328.   BEGIN
  329.     newScreen (mainGraphWdw.screen.start, oldScreen);
  330.     
  331.     setClipping (mainGraphWdw.screen);
  332.     SetFillColor (dev, white);
  333.     SetFillType (dev, solidFill);
  334.     FillRectangle (dev, Rect (0, 0, mainGraphWdw.screen.w,
  335.                               mainGraphWdw.screen.h));
  336.     RedrawWindow (mainGraphWdw.wdw);
  337.     disableClipping;
  338.     
  339.     restoreScreen (oldScreen);
  340.   END Clear;
  341.   
  342. PROCEDURE Dot (x, y: INTEGER);
  343.  
  344.   VAR   oldScreen: ADDRESS;
  345.  
  346.   BEGIN
  347.     newScreen (mainGraphWdw.screen.start, oldScreen);
  348.     
  349.     setClipping (mainGraphWdw.screen);
  350.     SetMarkerColor (dev, black);
  351.     SetMarkerType (dev, pointMark);
  352.     Mark (dev, Pnt (x, y));
  353.     UpdateWindow (mainGraphWdw.wdw, redrawServer, ADR (mainGraphWdw),
  354.                   Rect (x, y, 1, 1));
  355.     disableClipping;
  356.     
  357.     restoreScreen (oldScreen);
  358.   END Dot;
  359.   
  360. PROCEDURE SetPen (x, y: INTEGER);
  361.  
  362.   BEGIN
  363.     mainGraphWdw.turtle.pos := Pnt (x, y);
  364.   END SetPen;
  365.   
  366. PROCEDURE TurnTo (d: INTEGER);
  367.  
  368.   BEGIN
  369.     mainGraphWdw.turtle.angle := d;
  370.   END TurnTo;
  371.   
  372. PROCEDURE Turn (d: INTEGER);
  373.  
  374.   BEGIN
  375.     WITH mainGraphWdw.turtle DO
  376.       angle := angle + d;
  377.       WHILE angle > 360 DO angle := angle - 360 END;
  378.       WHILE angle < -360 DO angle := angle + 360 END;
  379.     END;
  380.   END Turn;
  381.   
  382. PROCEDURE Move (d: INTEGER);
  383.  
  384.   BEGIN
  385.     WITH mainGraphWdw.turtle DO
  386.       MoveTo (pos.x + SHORT (entier (FLOAT (d)
  387.                                      * cos (FLOAT (angle) * pi / 180.0))),
  388.               pos.y + SHORT (entier (FLOAT (d)
  389.                                      * sin (FLOAT (angle) * pi / 180.0))));
  390.     END;
  391.   END Move;
  392.   
  393. PROCEDURE MoveTo (x, y: INTEGER);
  394.  
  395.   VAR   oldScreen: ADDRESS;
  396.         frame    : Rectangle;
  397.  
  398.   BEGIN
  399.     newScreen (mainGraphWdw.screen.start, oldScreen);
  400.     
  401.     WITH mainGraphWdw DO
  402.     
  403.       setClipping (screen);
  404.       SetLineColor (dev, black);
  405.       SetLineType (dev, solidLn);
  406.       
  407.       Line (dev, turtle.pos, Pnt (x, y));
  408.       
  409.       frame := Rect (turtle.pos.x, turtle.pos.y,
  410.                      x - turtle.pos.x + 1, y - turtle.pos.y + 1);
  411.       IF frame.w < 0 THEN
  412.         frame.x := frame.x + frame.w - 1;
  413.         frame.w := - frame.w;
  414.       END;
  415.       IF frame.h < 0 THEN
  416.         frame.y := frame.y + frame.h - 1;
  417.         frame.h := - frame.h;
  418.       END;
  419.       
  420.       UpdateWindow (wdw, redrawServer, ADR (mainGraphWdw), frame);
  421.       
  422.       turtle.pos := Pnt (x, y);
  423.       
  424.       disableClipping;
  425.       
  426.     END;
  427.     
  428.     restoreScreen (oldScreen);
  429.   END MoveTo;
  430.   
  431. PROCEDURE Circle (x, y, r: INTEGER);
  432.  
  433.   VAR   oldScreen: ADDRESS;
  434.  
  435.   BEGIN
  436.     newScreen (mainGraphWdw.screen.start, oldScreen);
  437.     
  438.     setClipping (mainGraphWdw.screen);
  439.     SetLineColor (dev, black);
  440.     SetLineType (dev, solidLn);
  441.     VDIOutputs.Circle (dev, Pnt (x, y), r);
  442.     UpdateWindow (mainGraphWdw.wdw, redrawServer, ADR (mainGraphWdw),
  443.                   Rect (x - r - 1, y - r - 1, 2 * r + 2, 2 * r + 2));
  444.     disableClipping;
  445.     
  446.     restoreScreen (oldScreen);
  447.   END Circle;
  448.   
  449. PROCEDURE Write (ch: CHAR);
  450.  
  451.   BEGIN
  452.     WriteString (ch);
  453.   END Write;
  454.   
  455. PROCEDURE WriteString (str: ARRAY OF CHAR);
  456.  
  457.   VAR   oldScreen: ADDRESS;
  458.  
  459.   BEGIN
  460.     newScreen (mainGraphWdw.screen.start, oldScreen);
  461.     
  462.     setClipping (mainGraphWdw.screen);
  463.     SetTextColor (dev, black);
  464.     SetTextEffects (dev, TEffectSet{});
  465.     GrafText (dev, mainGraphWdw.turtle.pos, str);
  466.     UpdateWindow (mainGraphWdw.wdw, redrawServer, ADR (mainGraphWdw),
  467.                   TransRect (TextExtent (dev, str), mainGraphWdw.turtle.pos));
  468.     disableClipping;
  469.     
  470.     restoreScreen (oldScreen);
  471.   END WriteString;
  472.   
  473. PROCEDURE IdentifyPos (VAR x, y: INTEGER);
  474.  
  475.   BEGIN
  476.     x := mainGraphWdw.turtle.pos.x;
  477.     y := mainGraphWdw.turtle.pos.y;
  478.   END IdentifyPos;
  479.   
  480.  
  481.                         (*  managment  *)
  482.                         (*  =========  *)
  483.  
  484. PROCEDURE termProc;
  485.  
  486.   BEGIN
  487.     IF mainGraphWdw.wdw # NoWindow THEN DeleteWindow (mainGraphWdw.wdw) END;
  488.     DEALLOCATE (mainGraphWdw.screen.start, 0L);
  489.     ExitGem (gemHdl);
  490.   END termProc;
  491.  
  492.  
  493. VAR     wsp      : MemArea;
  494.         termCrr  : TermCarrier;
  495.         devParm  : PtrDevParm;
  496.         
  497.         success  : BOOLEAN;
  498.         oldScreen: ADDRESS;
  499.  
  500. BEGIN
  501.  
  502.   mainGraphWdw.wdw := NoWindow;
  503.  
  504.   (*  Init. GEM.
  505.    *)
  506.   InitGem (RC, dev, success); IF ~ success THEN cantInitGem END;
  507.   gemHdl := CurrGemHandle ();
  508.   
  509.   (*  Inquire screen size and number of planes, used from the VDI
  510.    *  and alloc. a compatible screen.
  511.    *)
  512.    
  513.   devParm := DeviceParameter (dev);
  514.     
  515.   mainGraphWdw.screen.w := 640 (*devParm^.rasterWidth + 1*);
  516.   mainGraphWdw.screen.h := 400 (*devParm^.rasterHeight + 1*);
  517.   mainGraphWdw.screen.standardForm := FALSE;
  518.   mainGraphWdw.screen.words := 40 (*(mainGraphWdw.screen.w + 15) DIV 16*);
  519.   mainGraphWdw.screen.planes := 1 (*devParm^.maxRasterPls*);
  520.   
  521.   ALLOCATE (mainGraphWdw.screen.start, 2L * LONG (mainGraphWdw.screen.words)
  522.                                        * LONG (mainGraphWdw.screen.h));
  523.   IF mainGraphWdw.screen.start = NIL THEN reportOutOfMem END;
  524.   
  525.   (*  Init. a window, clear its contens and show it.
  526.    *)
  527.    
  528.   CreateWindow (mainGraphWdw.wdw,
  529.                 WdwElemSet{sizeElem, moveElem, scrollElem, titleElem},
  530.                 redrawServer, activeServer, closeServer, moveSizeServer,
  531.                 scrollServer, ADR (mainGraphWdw),
  532.                 ScrollCopyAlways);
  533.   SetWindowString (mainGraphWdw.wdw, titleWdwStr, mainWdwName);
  534.   
  535.   newScreen (mainGraphWdw.screen.start, oldScreen);
  536.   SetFillColor (dev, white);
  537.   SetFillType (dev, solidFill);
  538.   FillRectangle (dev, Rect (0, 0, mainGraphWdw.screen.w,
  539.                             mainGraphWdw.screen.h));
  540.   restoreScreen (oldScreen);
  541.   
  542.   OpenWindow (mainGraphWdw.wdw);
  543.   ShareTime (0L);
  544.   
  545.   (*  Catch the process termination, for deinit.
  546.    *)
  547.   wsp.bottom := ADR (Stack);
  548.   wsp.length := SIZE (Stack);
  549.   CatchProcessTerm (termCrr, termProc, wsp);
  550.   
  551. END EasyGraphics.
  552. (* $FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFEBD6FA$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2$FFED31B2ü$0000382CT.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$000037C9$000037EE$00003815$0000382C$00002B1E$000007D3$000032C6$000032F4$000032DD$FFEA5C66$0000383D$000006DE$0000371B$00003735$00003759$00003774ÉÇü*)
  553.